/*****************************************************************************
 * Copyright (c) 2019, Nations Technologies Inc.
 *
 * All rights reserved.
 * ****************************************************************************
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * - Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the disclaimer below.
 *
 * Nations' name may not be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY NATIONS "AS IS" AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
 * DISCLAIMED. IN NO EVENT SHALL NATIONS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
 * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 * ****************************************************************************/

/**
 * @file main.c
 * @author Nations 
 * @version v1.0.0
 *
 * @copyright Copyright (c) 2019, Nations Technologies Inc. All rights reserved.
 */
#include "main.h"
#include <stdio.h>
#include <stdint.h>
#include "hardware.h"

/**
 * @brief  Main program.
 */
 
void	RAM_Initial(void)
{
	Error_Flg.value = 0;
#if 0	
	machine.TZSensorPower = false;
	machine.ShuiFaPower = false;
	machine.ChuChouYePower = false;
	machine.FanPower = false;
#endif	
	machine.DeviceWorking = false;
	machine.TZSensorPowerOff = false;
	WuHuaCtrl.WuHuaStatus = WUHUA_PowerOff;
	swDelay = 0;
	SettingPhase = 0;
	InitialSetting();
#if 0	
	Led_Ctrl.STATUS.value = ALL_LEDON;
	Led_Ctrl.FLS.value = ALL_LED_FLASH_OFF;
#endif	
}


void	InitialMonitor(void)
{
		TIM_TimeBaseInitType TIM_TimeBaseStructure;
    NVIC_InitType NVIC_InitStructure;

    RCC_EnableAPB1PeriphClk(RCC_APB1_PERIPH_TIM6, ENABLE);

    /* Enable the TIM2 global Interrupt */
    NVIC_InitStructure.NVIC_IRQChannel                   = LPTIM_TIM6_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPriority           = 1;
    NVIC_InitStructure.NVIC_IRQChannelCmd                = ENABLE;

    NVIC_Init(&NVIC_InitStructure);
	
		TIM_TimeBaseStructure.Period    = SystemCoreClock/1000;
    TIM_TimeBaseStructure.Prescaler = 9;
    TIM_TimeBaseStructure.ClkDiv    = 0;
    TIM_TimeBaseStructure.CntMode   = TIM_CNT_MODE_UP;

    TIM_InitTimeBase(TIM6, &TIM_TimeBaseStructure);

    /* Prescaler configuration */
 //   TIM_ConfigPrescaler(TIM6, 10, TIM_PSC_RELOAD_MODE_IMMEDIATE);

    /* TIM6 enable update irq */
    TIM_ConfigInt(TIM6, TIM_INT_UPDATE, ENABLE);

    /* TIM6 enable counter */
    TIM_Enable(TIM6, ENABLE);
}
/**
 * @brief  Inserts a delay time.
 * @param count specifies the delay time length.
 */
void Delay(uint32_t count)
{
    for (; count > 0; count--)
        ;
}

void	TIM8_BRK_UP_TRG_COM_IRQHandler(void)
{
    if (TIM_GetIntStatus(TIM8, TIM_INT_UPDATE) != RESET)
    {
      TIM_ClrIntPendingBit(TIM8, TIM_INT_UPDATE);
   }
}

extern void DisplayErrorCode(U8 ErrorCode);
extern void StopDevice(void);
void	Check_Error(void)
{
	U8 ErrorCode;
	while (Error_Flg.value != 0)
	{
		StopDevice();
		Buzzer(3);
		if (Error_Flg.BIT.Program_Err || Error_Flg.BIT.Ram_Err)
			ErrorCode = 1;
		else if (Error_Flg.BIT.ChuChouYe_Err)
			ErrorCode = 2;
		else if (Error_Flg.BIT.Water_Err)
		{
			Check_Water_Sensor();
			ErrorCode = 3;
		}
		else if (Error_Flg.BIT.AddWater_Err)
			ErrorCode = 4;
		else if (Error_Flg.BIT.AddChuChouYe_Err)
			ErrorCode = 5;
		else
			ErrorCode = 0xff;
		DisplayErrorCode (ErrorCode);
		delay_ms(3000);
	}
}

void MainSetting(void)
{
	bool UpdateLED = true;
	u8 key,idx;
	
	swDelay = SETTING_IDLE_TIME;
	BackupSetting = CurSetting;
	WaitReleaseKey();
	while(true)
	{
		if (UpdateLED)
		{
			UpdateLED = false;
			UpdateLEDStatus();
		}
		key = ReadKey();
		if (key != NO_KEY_PRESSED)
			WaitReleaseKey();
		switch (key)
		{
			case	FORWARD_KEY:
				if (SettingPhase < Setting_Item_Max - 1)
				{
					SettingPhase ++;
					UpdateLED = true;
				}
				break;
			case	BACKWARD_KEY:
				if (SettingPhase > 0)
				{
					SettingPhase --;
					UpdateLED = true;
				}
				break;
			case	MINUS_KEY:
				idx = SettingPhase;
				if (CurSetting.data[idx] >= setting_item[idx].step)
					CurSetting.data[idx] -= setting_item[idx].step;
				else
					CurSetting.data[idx] = setting_item[idx].min;					
				UpdateLED = true;				
				break;
			case	PLUS_KEY :
				idx = SettingPhase;
				if (setting_item[idx].max - CurSetting.data[idx] >= setting_item[idx].step)
					CurSetting.data[idx] += setting_item[idx].step;
				else
					CurSetting.data[idx] = setting_item[idx].max;					
				UpdateLED = true;
				break;
			default:
				break;
		}
		if (key != NO_KEY_PRESSED)
			swDelay = SETTING_IDLE_TIME;
		if(swDelay == 0)
			break;
	}	
	SaveSetting((U8 *)&CurSetting,sizeof(SETTING_STRUCT));	
	DisplayStatus(false,false,NULL);
	if ((BackupSetting.SetItem.Time_Hour != CurSetting.SetItem.Time_Hour) || (BackupSetting.SetItem.Time_Minute != CurSetting.SetItem.Time_Minute))
	{
		RTC_TimeStructure.H12 = RTC_AM_H12;
		RTC_TimeStructure.Hours = CurSetting.SetItem.Time_Hour;
		RTC_TimeStructure.Minutes = CurSetting.SetItem.Time_Minute;
		RTC_TimeStructure.Seconds = 0;
		RTC_ConfigTime(RTC_FORMAT_BIN, &RTC_TimeStructure);
	}
}

int main(void)
{
	u8 key;
	Board_Initial();
	DisplayStatus(true,false,NULL);
	LED_PowerOff(LED_START_WORKING);
	LED_PowerOn(LED_POWER_ON_STS);

	RTC_Config();
	RTC_DateRegulate();
	RTC_TimeRegulate();
	TZ_Sensor_PowerOn(true);
	while (1)
	{
//		delay_ms(1000);
		ProcessMachineStatus();
  	Check_Error();
		key = ReadKey();		
		WaitReleaseKey();
		switch (key)
		{
			case	START_KEY:
				StartDevice();
				break;
			case	CHOUYE_KEY:
				ChouYePowerOn();
				break;
			case	LEDOFF_KEY:
				DisplayStatus(false,false,NULL);
				break;
			case	SETTING_KEY:
				MainSetting();
				break;
			case	KEY_ZERO_PRESSED:
				Calibrate(&CurSetting.HXOffset,&CurSetting.HXCalibrate);
				SaveSetting((u8 *)(&CurSetting),sizeof(SETTING_STRUCT));	
//				Buzzer(3);
				break;
			default:
				break;
		}
	}
}

/**
 * @brief Assert failed function by user.
 * @param file The name of the call that failed.
 * @param line The source line number of the call that failed.
 */
#ifdef USE_FULL_ASSERT
void assert_failed(const uint8_t* expr, const uint8_t* file, uint32_t line)
{
    while (1)
    {
    }
}
#endif // USE_FULL_ASSERT

/**
 * @}
 */
